/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Network;


import IO.Question;

import client.MainFrameClient;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Vo Nguyen Khang
 */
public class NetworkClient extends NetworkConnection{



    private String hostname;
    private int port;
    Socket clientSocket;

    public IO.Exam exam;
    BufferedReader incoming;
    PrintWriter outgoing;

    MainFrameClient frameClient = null;





    public NetworkClient(String hostname, int port) {
        super();
        this.hostname = hostname;
        this.port = port;
        try {
            clientSocket = new Socket(hostname, port);
            incoming = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            outgoing = new PrintWriter(clientSocket.getOutputStream());
        } catch (UnknownHostException ex) {
            Logger.getLogger(NetworkClient.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(NetworkClient.class.getName()).log(Level.SEVERE, null, ex);
        }
      
    }

    public NetworkClient(String hostname, int port, MainFrameClient frame) {
        super();
        this.hostname = hostname;
        this.port = port;
        this.frameClient  = frame;
        try {
            clientSocket = new Socket(hostname, port);
            incoming = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            outgoing = new PrintWriter(clientSocket.getOutputStream());
        } catch (UnknownHostException ex) {
            Logger.getLogger(NetworkClient.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(NetworkClient.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public NetworkClient() {
        super();
        try {
            clientSocket = new Socket("127.0.0.1", 8081);
        } catch (UnknownHostException ex) {
            Logger.getLogger(NetworkClient.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(NetworkClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        
    }

    /**
     *
     * @return
     */

    public boolean  checkConnection()
    {
        if(clientSocket.isClosed() || !clientSocket.isConnected())
            return false;
        return true;
    }

    /**
     * open Connection for listening with specific port
     * @param port: specific config port for listenning
     * @return
     */

    public boolean connect(MainFrameClient frame)
    {
//        outgoing.println(MSG_CLIENT_REQUEST);
        outgoing.println(MSG_CLIENT_REQUEST);
        outgoing.flush();
        try {
            String msg = incoming.readLine();
            processMsg(msg,frame);
        } catch (IOException ex) {
            Logger.getLogger(NetworkClient.class.getName()).log(Level.SEVERE, null, ex);
        }

        beginWaitForStart(frame);
        
        return true;
    }

    /**
     * create a thread that wait for server send message start the exam
     * @return
     */

    public boolean beginWaitForStart(MainFrameClient frame)
    {
        if( !exam.isActive)
        {
            this.frameClient = frame;
            System.out.println("HELLO");
            
            new WaitingForStart(exam,incoming,frame);
        }

        return true;
    }

    public boolean closeConnection() {

        throw new UnsupportedOperationException("Not supported yet.");
    }


    public void processMsg(String msg, MainFrameClient frame)
    {
        if(msg.equals(MSG_SERVER_START))
        {
            exam.isActive = true;
            exam.stop = false;
            System.out.println("Start the exam");
            frame.beginExam();
            exam.startClient();            
        }        
        else if(msg.equals(MSG_SERVER_TIMEOUT))
        {
            exam.stop = true;
            
            System.out.println(1);            
        }
        else if(msg.startsWith(MSG_SERVER_SUBMIT_REPLY))
        {
            
        }
        else if(msg.equals(MSG_SERVER_REPLY))
        {
            System.out.println(1);
             try {

                    System.out.println(3);
                    // process It -> send data to client

                    exam = new IO.Exam();

                    exam.setTitle(incoming.readLine());
                    exam.setLength(incoming.readLine());
                    exam.setDescription(incoming.readLine());

                    int n = Integer.valueOf(incoming.readLine());
                    exam.setTotalQuestion(0);

                    System.out.println(exam.getTitle());

                    for(int i = 0 ; i < n ; i++)
                    {
                        String number = incoming.readLine();
                        String statement = incoming.readLine();
                        String numChoice = incoming.readLine();
//                        outgoing.println(question.getNumber().toString());
//                        outgoing.println(question.getStatement());
//                        outgoing.println(String.valueOf(question.getNumberOfChoice()));
                        List<String> listChoices = new ArrayList<String>();


                        for(int j = 0; j < Integer.valueOf(numChoice);j++)
                        {
                            listChoices.add(incoming.readLine());
                        }
                        exam.addOneQuestion(number, statement, listChoices);
                    }

                    frame.setLabelStatus("Successful connected and receive data");

                    



//                    incoming.close();


                } catch (IOException ex) {
                Logger.getLogger(NetworkClient.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        else
            System.out.println("HUHU");
                
    }
    

    public boolean Submit(String stdID, String stdName, MainFrameClient frame)
    {
        if(frame == null && this.frameClient!=null)
            frame = this.frameClient;

        if(exam.isActive && !exam.stop)
        {
            outgoing.println(MSG_CLIENT_SUBMITTED);
            outgoing.flush();
            outgoing.println(stdID);
            outgoing.println(stdName);
            outgoing.flush();

            for(int i = 0; i < frame.answerList.size(); i++)
            {
                outgoing.println(frame.answerList.get(i).getNumQuestion());
                outgoing.println(frame.answerList.get(i).getAnswer());
                outgoing.flush();
            }

            outgoing.println("__END_OF_QUESTION__");
            outgoing.flush();

            try {
                String msg = incoming.readLine();
                if(msg.charAt(msg.length()-1)=='Y')
                {
                    System.out.println("Submit successfully");
                    //frame.showDialogMessage("Submitted successfully");
                    frame.setLabelStatus("Submit successfully");
                }
                else if(msg.charAt(msg.length()-1)=='N')
                {
                    System.out.println("Submit unsuccessfully");
                    //frame.showDialogMessage("Submitted successfully");
                    frame.setLabelStatus("Submit unsuccessfully");
                }
                else
                    System.out.println("Unknow error"+ msg);
            } catch (IOException ex) {
                Logger.getLogger(NetworkClient.class.getName()).log(Level.SEVERE, null, ex);
            }

            return true;
        }
        return false;
    }

    

    public static void main(String args[]) {
//        NetworkClient client = new NetworkClient("127.0.0.1",123);
//        client.connect();
//        System.out.println(client.exam.getDescription());

    }

    static class  WaitingForStart extends Thread
    {
        BufferedReader incoming;
        IO.Exam exam;
        MainFrameClient frameClient;

        public WaitingForStart(IO.Exam exam, BufferedReader incoming,MainFrameClient frame)
        {
            this.exam = exam;
            this.incoming = incoming;
            this.frameClient =frame;
            start();
        }

        @Override
        public void run()
        {
//            boolean stop = false;
            while(!exam.isActive)
            {
                try {
                    String msg = incoming.readLine();
                    if(MSG_SERVER_START.equals(msg))
                    {
//                        stop = true;
                        exam.isActive = true;
                        exam.stop = false;
                        System.out.println("Start the exam");
                        
                        frameClient.beginExam();
                        //frameClient.setLabelStatus("The exam is started");

                        // Start the timer
                        // End "start the timer"


                        break;
                    }
                } catch (IOException ex) {
                    Logger.getLogger(NetworkClient.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }


}
